package com.cloudwise.monitoring_system.jmx;

import com.cloudwise.monitoring_system.entity.MonitorValue;
import com.cloudwise.monitoring_system.service.mysqlService.MonitorValueService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author Reisen
 * @description: MBean接口的实现类
 * @date 2021/5/26 14:40
 */
@Slf4j
@Component
public class JMXMonitor implements JMXMonitorMBean{
    @Resource
    private MonitorValueService monitorValueService;
    double memoryUsedRateHeap=0;
    double memoryUsedRateNoHeap=0;


    /**
     * 监控内存信息每10秒刷新一次，保证取到较新的值
     */
    @Scheduled(cron = "*/10 * * * * ?")
    private void monitorMemory(){

        MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();


        MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();
        MemoryUsage nonHeapMemoryUsage = memoryMXBean.getNonHeapMemoryUsage();
        double heapMemoryUsageMax = bytesFormat(heapMemoryUsage.getCommitted());

        double heapMemoryUsageUsed = bytesFormat(heapMemoryUsage.getUsed());
        //堆内存展荣
        memoryUsedRateHeap = rateFormat(heapMemoryUsageUsed/heapMemoryUsageMax);
        double nonHeapMemoryUsageMax = bytesFormat(nonHeapMemoryUsage.getCommitted());
        double nonHeapMemoryUsageUsed = bytesFormat(nonHeapMemoryUsage.getUsed());
        //非堆内存占用
        memoryUsedRateNoHeap = rateFormat(nonHeapMemoryUsageUsed/nonHeapMemoryUsageMax);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = new Date();
        String createTime=simpleDateFormat.format(date);
        MonitorValue monitorValue = new MonitorValue();
        MonitorValue monitorValue2 = new MonitorValue();
        //将堆内存占用结果插入数据库
        monitorValue.setUnitId(5);
        monitorValue.setMonitorValue(memoryUsedRateHeap);
        monitorValue.setCreateTime(createTime);
        MonitorValue result1 = monitorValueService.insert(monitorValue);
        //将非堆内存占用结果插入数据库
        monitorValue2.setUnitId(6);
        monitorValue2.setMonitorValue(memoryUsedRateNoHeap);
        monitorValue2.setCreateTime(createTime);
        MonitorValue result2 = monitorValueService.insert(monitorValue2);
        if (result1!=null && result2 !=null){
            log.info("监控到jvm内存占用，数据库新增一条数据");
            log.info("监控到jvm内存占用，数据库新增一条数据");
        }


    }

    /**
     * 将byte转为Mb
     * @param bytes
     * @return
     */
    private static double bytesFormat(long bytes){
        return (double)bytes/1024/1024;
    }

    /**
     * 化为比率 100%
     * @param d
     * @return
     */
    private static double rateFormat(double d){
        NumberFormat nf = NumberFormat.getInstance();
        nf.setMaximumFractionDigits(4);
        return Double.parseDouble(nf.format(d))*100;
    }

    @Override
    public double getMemoryUsedRateHeap() {
        return memoryUsedRateHeap;
    }

    @Override
    public double getMemoryUsedRateNoHeap() {
        return memoryUsedRateNoHeap;
    }
}
